package com.smedi.ismedi.authoritymanagement.core.port.adapter.persistence.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.RoleAssignment;
import com.smedi.ismedi.authoritymanagement.core.domain.aggregatemodel.RoleMember;
import com.smedi.ismedi.authoritymanagement.core.domain.dto.RoleAssignmentQuery;
import com.smedi.ismedi.authoritymanagement.core.domain.repository.RoleMemberRepository;
import com.smedi.ismedi.authoritymanagement.core.port.adapter.convert.AdapterConverter;
import com.smedi.ismedi.authoritymanagement.core.port.adapter.persistence.model.RoleMemberEntity;
import com.smedi.ismedi.authoritymanagement.core.port.adapter.persistence.mybatis.mapper.RoleMemberMapper;
import com.smedi.ismedi.database.starter.annotation.SkipSqlPermission;
import com.smedi.ismedi.web.starter.util.DozerUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.List;

@Slf4j
@Repository
@AllArgsConstructor
public class RoleMemberRepositoryImpl extends ServiceImpl<RoleMemberMapper, RoleMemberEntity> implements RoleMemberRepository, IService<RoleMemberEntity> {
    private final DozerUtil dozerUtil;
    private final AdapterConverter adapterConverter;

    @Override
    public int selectCountByRoleIdAndPersonId(Long roleId, Long personId) {
        QueryWrapper<RoleMemberEntity> wrapper = new QueryWrapper();
        wrapper.eq("role_id", roleId)
                .eq("person_id", personId);
        return this.getBaseMapper().selectCount(wrapper);
    }

    @Override
    public RoleMember doInsert(RoleMember data) {
        RoleMemberEntity roleMemberEntity = dozerUtil.convertor(data, RoleMemberEntity.class);
        this.getBaseMapper().insert(roleMemberEntity);
        return dozerUtil.convertor(roleMemberEntity, RoleMember.class);
    }

    @Override
    public void doDeleteByRoleMemberId(Long roleMemberId) {
        QueryWrapper<RoleMemberEntity> wrapper = new QueryWrapper();
        wrapper.eq("id", roleMemberId);

        this.getBaseMapper().delete(wrapper);
    }

    @Override
    public RoleMember selectByRoleMemberId(Long roleMemberId) {
        QueryWrapper<RoleMemberEntity> wrapper = new QueryWrapper();
        wrapper.eq("id", roleMemberId);

        return dozerUtil.convertor(this.getBaseMapper().selectOne(wrapper), RoleMember.class);
    }

    @Override
    public int selectCountByRoleId(Long roleId) {
        QueryWrapper<RoleMemberEntity> wrapper = new QueryWrapper();
        wrapper.eq("role_id", roleId);
        return this.getBaseMapper().selectCount(wrapper);
    }

    @Override
    public List<RoleMember> selectRoleMemberByPersonId(Long personId) {
        QueryWrapper<RoleMemberEntity> wrapper = new QueryWrapper();
        wrapper.eq("person_id", personId)
                .orderByDesc("id");
        return dozerUtil.convertor(this.getBaseMapper().selectList(wrapper), RoleMember.class);
    }

    @Override
    public List<RoleMember> selectRoleMemberByRoleId(Long roleId) {
        QueryWrapper<RoleMemberEntity> wrapper = new QueryWrapper();
        wrapper.eq("role_id", roleId);

        return dozerUtil.convertor(this.getBaseMapper().selectList(wrapper), RoleMember.class);
    }

    @Override
    @SkipSqlPermission
    public List<RoleMember> selectRoleMemberByRoleId(List<Long> roleIds) {
        QueryWrapper<RoleMemberEntity> wrapper = new QueryWrapper<>();
        wrapper.in("role_id", roleIds);

        return dozerUtil.convertor(this.getBaseMapper().selectList(wrapper), RoleMember.class);
    }

    @Override
    public List<RoleAssignment> getRoleAssignmentList(RoleAssignmentQuery roleAssignmentQuery) {
        LambdaQueryWrapper<RoleMemberEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(roleAssignmentQuery.getRoleIds()), RoleMemberEntity::getRoleId, roleAssignmentQuery.getRoleIds());
        lambdaQueryWrapper.eq(ObjectUtils.isNotNull(roleAssignmentQuery.getRoleId()), RoleMemberEntity::getRoleId, roleAssignmentQuery.getRoleId());
        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(roleAssignmentQuery.getPersonIds()), RoleMemberEntity::getPersonId, roleAssignmentQuery.getPersonIds());
        lambdaQueryWrapper.eq(ObjectUtils.isNotNull(roleAssignmentQuery.getPersonId()), RoleMemberEntity::getPersonId, roleAssignmentQuery.getPersonId());

        List<RoleMemberEntity> roleMemberEntities = this.baseMapper.selectList(lambdaQueryWrapper);

        return adapterConverter.roleMemberEntityToRoleAssignment(roleMemberEntities);
    }

    @Override
    public List<RoleAssignment> getRoleAssignmentListWithoutToken(RoleAssignmentQuery roleAssignmentQuery) {
        LambdaQueryWrapper<RoleMemberEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(roleAssignmentQuery.getRoleIds()), RoleMemberEntity::getRoleId, roleAssignmentQuery.getRoleIds());
        lambdaQueryWrapper.eq(ObjectUtils.isNotNull(roleAssignmentQuery.getRoleId()), RoleMemberEntity::getRoleId, roleAssignmentQuery.getRoleId());
        lambdaQueryWrapper.in(CollectionUtils.isNotEmpty(roleAssignmentQuery.getPersonIds()), RoleMemberEntity::getPersonId, roleAssignmentQuery.getPersonIds());
        lambdaQueryWrapper.eq(ObjectUtils.isNotNull(roleAssignmentQuery.getPersonId()), RoleMemberEntity::getPersonId, roleAssignmentQuery.getPersonId());

        List<RoleMemberEntity> roleMemberEntities = this.baseMapper.selectList(lambdaQueryWrapper);

        return adapterConverter.roleMemberEntityToRoleAssignment(roleMemberEntities);
    }
}
